package com.smedi.ismedi.progress.core.port.adapter.persistence.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smedi.ismedi.constructionproject.api.dto.response.ProjectBasicResponse;
import com.smedi.ismedi.progress.api.dto.response.KeyTaskResponse;
import com.smedi.ismedi.progress.core.application.command.ProjectBriefListQuery;
import com.smedi.ismedi.progress.core.application.command.ProjectBriefReportDetailQuery;
import com.smedi.ismedi.progress.core.application.command.ProjectBriefReportEditAllCommand;
import com.smedi.ismedi.progress.core.application.command.ProjectBriefReportEditCommand;
import com.smedi.ismedi.progress.core.domain.aggregatemodel.ProjectBriefReport;
import com.smedi.ismedi.progress.core.domain.aggregatemodel.ProjectBriefReportDetail;
import com.smedi.ismedi.progress.core.domain.dto.ProjectBriefReportVo;
import com.smedi.ismedi.progress.core.domain.repository.ProjectBriefReportRepository;
import com.smedi.ismedi.progress.core.infrastructure.constant.EngieerStatusEnum;
import com.smedi.ismedi.progress.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.progress.core.port.adapter.persistence.model.*;
import com.smedi.ismedi.progress.core.port.adapter.persistence.mybatis.mapper.*;
import com.smedi.ismedi.progress.core.port.adapter.service.ProjectRemoteService;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

import static com.smedi.ismedi.progress.core.infrastructure.constant.ConstantField.BRIEF_NAME;
import static com.smedi.ismedi.progress.core.infrastructure.constant.ConstantField.PROJECT_TYPE;

/**
 * @author liaojiajie
 * @Date 2022/9/16 13:45
 */
@Service
@RequiredArgsConstructor
public class ProjectBriefReportRepositoryImpl implements ProjectBriefReportRepository {
    @Value("${general-hospital.id}")
    private String generalHospitalId;

    private final ProjectBriefReportMapper projectBriefReportMapper;
    private final ProjectBriefReportDetailMapper projectBriefReportDetailMapper;
    private final ProjectBriefAssociationMapper projectBriefAssociationMapper;
    private final ProgressMapper progressMapper;
    private final ProgressDetailMapper progressDetailMapper;
    private final ProgressReportDetailMapper progressReportDetailMapper;
    private final AdapterConverter adapterConverter;
    private final ProjectRemoteService projectRemoteService;

    @Override
    public Page<ProjectBriefReport> getProjectBriefList(ProjectBriefListQuery projectBriefListQuery) {
        Page<ProjectBriefReportEntity> page = new Page<>(projectBriefListQuery.getOffset(), projectBriefListQuery.getPageSize());
        Page<ProjectBriefReport> projectBriefReportList = new Page<>();
        LambdaQueryWrapper<ProjectBriefReportEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String statisticalEndTime = projectBriefListQuery.getStatisticalEndTime() + "-31 23:59:59";
        String statisticalStartTime = projectBriefListQuery.getStatisticalEndTime() + "-01";
        String recordEndTime = projectBriefListQuery.getRecordEndTime() + " 23:59:59";
        lambdaQueryWrapper.eq(ObjectUtils.isNotNull(projectBriefListQuery.getOrganizationOrProjectId()), ProjectBriefReportEntity::getOrganizationOrProjectId, projectBriefListQuery.getOrganizationOrProjectId());
        lambdaQueryWrapper.between(ObjectUtils.isNotNull(projectBriefListQuery.getStatisticalStartTime()), ProjectBriefReportEntity::getStatisticalTime, statisticalStartTime, statisticalEndTime);
        lambdaQueryWrapper.between(ObjectUtils.isNotNull(projectBriefListQuery.getRecordStartTime()), ProjectBriefReportEntity::getRecordTime, projectBriefListQuery.getRecordStartTime(), recordEndTime);
        lambdaQueryWrapper.orderByDesc(ProjectBriefReportEntity::getStatisticalTime);
        //如果是项目简报
        if (PROJECT_TYPE.equals(projectBriefListQuery.getType())) {
            lambdaQueryWrapper.eq(ProjectBriefReportEntity::getType, 0L);
            projectBriefReportList = projectBriefReportMapper.getProjectBriefReportList(page, lambdaQueryWrapper);
        } else {
            lambdaQueryWrapper.eq(ProjectBriefReportEntity::getType, 1L);
            Page<ProjectBriefReportEntity> projectBriefReportEntityPage = projectBriefReportMapper.selectPage(page, lambdaQueryWrapper);
            projectBriefReportList = adapterConverter.projectBriefReportEntitiesToprojectBriefReports(projectBriefReportEntityPage);
        }
        return projectBriefReportList;
    }

    @Override
    public ProjectBriefReportVo getProjectBriefReportDetail(ProjectBriefReportDetailQuery projectBriefReportDetailQuery) {
        List<ProjectBriefReportDetail> projectBriefReportDetails = projectBriefReportMapper.getProjectBriefReportDetail(projectBriefReportDetailQuery.getId());
        List<Long> ids = projectBriefReportDetails.stream().map(ProjectBriefReportDetail::getId).collect(Collectors.toList());
        List<ProjectBriefReportDetail> projectBriefReportEntities = projectBriefReportMapper.geProjectRecordTime(ids);
        //记录时间一一对应
        projectBriefReportDetails.forEach(v->{
            for (ProjectBriefReportDetail briefReportDetail:projectBriefReportEntities) {
                if (v.getId().equals(briefReportDetail.getId())){
                    v.setRecordTime(briefReportDetail.getRecordTime());
                    break;
                }
            }
        });
        //如果是 总院  则未发布的 和 发布时间不超过24小时的  都不显示  某部分字段
        if (projectBriefReportDetails.stream().findFirst().get().getBriefReportType()==2){
            LocalDateTime now = LocalDateTime.now();
            projectBriefReportDetails.forEach(v -> {
                    if ( v.getStatus()==0 ||v.getStatus() == 1 && Duration.between(v.getRecordTime(), now).toDays() < 1) {
                        v.setMonthAllProgress("-");
                        v.setNextMonthNode("-");
                        v.setExistQuestionPrecautions("-");
                    }
                });
        }
        //主体院的
        if (projectBriefReportDetails.stream().findFirst().get().getBriefReportType()==1){
            projectBriefReportDetails.forEach(v -> {
                if (v.getStatus()==0) {
                    v.setMonthAllProgress("-");
                    v.setNextMonthNode("-");
                    v.setExistQuestionPrecautions("-");
                }
            });
        }
        ProjectBriefReportVo projectBriefReportVo = ProjectBriefReportVo.builder()
                .briefReportName(projectBriefReportDetails.stream().findFirst().get().getBriefReportName())
                .remarksInformation(projectBriefReportDetails.stream().findFirst().get().getRemarksInformation())
                .projectBriefReportDetails(projectBriefReportDetails).build();

        return projectBriefReportVo;
    }

    @Override
    public List<ProjectBriefReportVo> getProjectBriefReportDetailAll(ProjectBriefReportDetailQuery projectBriefReportDetailQuery) {
        List<ProjectBriefReportDetail> projectBriefReportDetails = projectBriefReportMapper.getProjectBriefReportDetailAll(projectBriefReportDetailQuery.getIds());

        List<Long> ids = projectBriefReportDetails.stream().map(ProjectBriefReportDetail::getId).collect(Collectors.toList());
        List<ProjectBriefReportDetail> projectBriefReportEntities = projectBriefReportMapper.geProjectRecordTime(ids);
        projectBriefReportDetails.forEach(v->{
            for (ProjectBriefReportDetail briefReportDetail:projectBriefReportEntities) {
                if (v.getId().equals(briefReportDetail.getId())){
                    v.setRecordTime(briefReportDetail.getRecordTime());
                    break;
                }
            }
        });
        if (projectBriefReportDetails.stream().findFirst().get().getBriefReportType()==2){
            LocalDateTime now = LocalDateTime.now();
            projectBriefReportDetails.forEach(v -> {
                if ( v.getStatus()==0 ||v.getStatus() == 1 && Duration.between(v.getRecordTime(), now).toDays() < 1) {
                    v.setMonthAllProgress("-");
                    v.setNextMonthNode("-");
                    v.setExistQuestionPrecautions("-");
                }
            });
        }
        if (projectBriefReportDetails.stream().findFirst().get().getBriefReportType()==1){
            projectBriefReportDetails.forEach(v -> {
                if (v.getStatus()==0) {
                    v.setMonthAllProgress("-");
                    v.setNextMonthNode("-");
                    v.setExistQuestionPrecautions("-");
                }
            });
        }
        List<ProjectBriefReportVo> allList = new ArrayList<>();
        projectBriefReportDetailQuery.getIds().forEach(v->{
            List<ProjectBriefReportDetail> oneList = new ArrayList<>();
            ProjectBriefReportVo.ProjectBriefReportVoBuilder projectBriefReportVo = ProjectBriefReportVo.builder();
            for (ProjectBriefReportDetail projectBriefReportDetail:projectBriefReportDetails){
                if (v.equals(projectBriefReportDetail.getBriefId())){
                    oneList.add(projectBriefReportDetail);
                    projectBriefReportVo = ProjectBriefReportVo.builder()
                            .projectBriefReportDetails(oneList)
                            .briefReportName(projectBriefReportDetail.getBriefReportName())
                            .remarksInformation(projectBriefReportDetail.getRemarksInformation());
                }
            }
//            for (ProjectBriefReportEntity projectBriefReport:projectBriefReportEntities) {
//                if (v.equals(projectBriefReport.getId())){
//                    projectBriefReportVo = ProjectBriefReportVo.builder()
//                            .projectBriefReportDetails(oneList)
//                            .briefReportName(projectBriefReport.getBriefReportName())
//                            .remarksInformation(projectBriefReport.getRemarksInformation());
//                    break;
//                }
//            }
        allList.add(projectBriefReportVo.build());
        });
        return allList;
    }

    @Override
    public Boolean projectBriefReportEdit(ProjectBriefReportEditAllCommand projectBriefReportEditCommand) {
        List<ProjectBriefReportDetailEntity> projectBriefReportDetails = adapterConverter.projectBriefReportEditCommandToProjectBriefReportDetailEntity(projectBriefReportEditCommand.getProjectBriefReportDetail());
        Integer num = projectBriefReportDetailMapper.updateBatch(projectBriefReportDetails, projectBriefReportEditCommand.getBriefReportType(),projectBriefReportEditCommand.getRemarksInformation(),LocalDateTime.now());
        if (num > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public Boolean projectBriefCreateTask() {
        LocalDateTime now = LocalDateTime.now();
        //所有项目以及对应组织
        List<ProjectBasicResponse> allProjectBasicList = projectRemoteService.getAllProjectBasicList();
        //所有进度项目
        List<ProgressEntity> allProject = progressMapper.findAllProject();
        //筛出在建项目
        List<ProjectBasicResponse>  projects = allProjectBasicList.stream().filter(p -> EngieerStatusEnum.CONSTRUCTING.name().equals(p.getProjectStatus())).collect(Collectors.toList());
        //选出在建项目中 在进度项目的 项目
        List<ProjectBasicResponse> constructingProjects = projects.stream().filter(a ->
                allProject.stream().map(ProgressEntity::getProjectId).anyMatch(id -> Objects.equals(a.getProjectId(), id))).collect(Collectors.toList());
        //排个序 组织升序  再项目升序
        List<ProjectBasicResponse> constructingProjectSort = constructingProjects.stream().sorted(Comparator.comparing(ProjectBasicResponse::getHrOrganizationId).thenComparing(ProjectBasicResponse::getProjectId))
                .collect(Collectors.toList());
        //企业组织ID 去重
        List<ProjectBasicResponse> mainCourtyardProjects = constructingProjects.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(
                        Comparator.comparing(
                                ProjectBasicResponse::getHrOrganizationId))), ArrayList::new));
        constructingProjectSort.forEach(v -> {
            ProjectBriefReportEntity projectBriefReportEntity = new ProjectBriefReportEntity();
            projectBriefReportEntity.setBriefReportName(v.getProjectName() + BRIEF_NAME + "(" + now.getYear() + "年" + now.getMonthValue() + "月" + ")");
            projectBriefReportEntity.setBriefReportType(0L);
            projectBriefReportEntity.setOrganizationOrProjectId(v.getProjectId());
            projectBriefReportEntity.setStatisticalTime(now);
            projectBriefReportEntity.setType(0L);
            //插入简报主表
            projectBriefReportMapper.insert(projectBriefReportEntity);
            ProjectBriefReportDetailEntity projectBriefReportDetailEntity = new ProjectBriefReportDetailEntity();
            projectBriefReportDetailEntity.setMainCourtyard(v.getHrOrganizationFullName());
            projectBriefReportDetailEntity.setProjectName(v.getProjectName());
            projectBriefReportDetailEntity.setStatus(0L);

            LambdaQueryWrapper<ProgressDetailEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ProgressDetailEntity::getProjectId, v.getProjectId());
            lambdaQueryWrapper.like(ProgressDetailEntity::getType, 4L);
            lambdaQueryWrapper.orderByAsc(ProgressDetailEntity::getSortIndex);
            List<ProgressDetailEntity> progressDetailEntityList = progressDetailMapper.selectList(lambdaQueryWrapper);
            //找出进度报告详情表 一级任务的进度
            if (progressDetailEntityList.size() > 0) {
                StringBuilder monthAllProgress = new StringBuilder();
                progressDetailEntityList.forEach(o -> {
                    monthAllProgress.append(o.getNamePrefix()).append(o.getName()).append("---").append(o.getPercentage()+"%").append("\n");
                });
                projectBriefReportDetailEntity.setMonthAllProgress(monthAllProgress.toString());
            }
            LambdaQueryWrapper<ProgressDetailEntity> wrapper = new LambdaQueryWrapper<>();
            LocalDateTime nextMonthFirst = now.minusMonths(-1).with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0);
            LocalDateTime nextMonthEnd = now.minusMonths(-1).with(TemporalAdjusters.lastDayOfMonth()).withHour(0).withMinute(0).withSecond(0);
            wrapper.eq(ProgressDetailEntity::getProjectId, v.getProjectId()).like(ProgressDetailEntity::getType, 4L)
                    .and(i->i.between(ProgressDetailEntity::getScheduleStartTime,nextMonthFirst,nextMonthEnd)
                    .or().between(ProgressDetailEntity::getScheduleEndTime,nextMonthFirst,nextMonthEnd)
                    .or().le(ProgressDetailEntity::getScheduleStartTime,nextMonthFirst).ge(ProgressDetailEntity::getScheduleEndTime,nextMonthEnd));

            wrapper.orderByAsc(ProgressDetailEntity::getSortIndex);
            List<ProgressDetailEntity> progressDetailEntityList1 = progressDetailMapper.selectList(wrapper);
            //找出下月一级任务
            if (progressDetailEntityList1.size() > 0) {
                StringBuilder nextMonthNode = new StringBuilder();
                progressDetailEntityList1.forEach(o -> {
                    nextMonthNode.append(o.getNamePrefix()).append(o.getName()).append("\n");
                });
                projectBriefReportDetailEntity.setNextMonthNode(nextMonthNode.toString());
            }
            projectBriefReportDetailMapper.insert(projectBriefReportDetailEntity);
            //插入关联表
            ProjectBriefAssociationEntity projectBriefAssociationEntity = new ProjectBriefAssociationEntity();
            projectBriefAssociationEntity.setProjectBriefReportId(projectBriefReportEntity.getId());
            projectBriefAssociationEntity.setProjectBriefReportDetailId(projectBriefReportDetailEntity.getId());
            projectBriefAssociationMapper.insert(projectBriefAssociationEntity);
        });
        //主体院简报
        mainCourtyardProjects.forEach(v -> {
            ProjectBriefReportEntity projectBriefReportEntity = new ProjectBriefReportEntity();
            projectBriefReportEntity.setBriefReportName(v.getHrOrganizationFullName() + BRIEF_NAME + "(" + now.getYear() + "年" + now.getMonthValue() + "月" + ")");
            projectBriefReportEntity.setBriefReportType(1L);
            projectBriefReportEntity.setOrganizationOrProjectId(v.getHrOrganizationId());
            projectBriefReportEntity.setStatisticalTime(now);
            projectBriefReportEntity.setType(1L);
            projectBriefReportMapper.insert(projectBriefReportEntity);
            LambdaQueryWrapper<ProjectBriefReportDetailEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ProjectBriefReportDetailEntity::getMainCourtyard, v.getHrOrganizationFullName());
            lambdaQueryWrapper.like(ProjectBriefReportDetailEntity::getCreatedDate,LocalDateTime.now().toString().substring(0,7));
            lambdaQueryWrapper.select(ProjectBriefReportDetailEntity::getId);
            List<ProjectBriefReportDetailEntity> idList = projectBriefReportDetailMapper.selectList(lambdaQueryWrapper);
            List<ProjectBriefAssociationEntity> associationList = new ArrayList<>();
            for (ProjectBriefReportDetailEntity projectBriefReportDetailEntity : idList) {
                ProjectBriefAssociationEntity association = new ProjectBriefAssociationEntity();
                association.setProjectBriefReportId(projectBriefReportEntity.getId());
                association.setProjectBriefReportDetailId(projectBriefReportDetailEntity.getId());
                associationList.add(association);
            }
            projectBriefAssociationMapper.insertBatch(associationList);
        });
        //总院简报
        ProjectBriefReportEntity projectBriefReportEntity = new ProjectBriefReportEntity();
        projectBriefReportEntity.setBriefReportName("总院" + BRIEF_NAME + "(" + now.getYear() + "年" + now.getMonthValue() + "月" + ")");
        projectBriefReportEntity.setBriefReportType(2L);
        projectBriefReportEntity.setOrganizationOrProjectId(Long.parseLong(generalHospitalId));
        projectBriefReportEntity.setStatisticalTime(now);
        projectBriefReportEntity.setType(1L);
        projectBriefReportMapper.insert(projectBriefReportEntity);
        LambdaQueryWrapper<ProjectBriefReportDetailEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(ProjectBriefReportDetailEntity::getCreatedDate,LocalDateTime.now().toString().substring(0,7));
        List<ProjectBriefReportDetailEntity> allDetail = projectBriefReportDetailMapper.selectList(lambdaQueryWrapper);
        List<ProjectBriefAssociationEntity> associationList = new ArrayList<>();
        for (ProjectBriefReportDetailEntity projectBriefReportDetailEntity : allDetail) {
            ProjectBriefAssociationEntity association = new ProjectBriefAssociationEntity();
            association.setProjectBriefReportId(projectBriefReportEntity.getId());
            association.setProjectBriefReportDetailId(projectBriefReportDetailEntity.getId());
            associationList.add(association);
        }
        projectBriefAssociationMapper.insertBatch(associationList);
        return true;
    }


}
